//
// Copyright (C) 2011 Adriano (University of Pisa)
// Copyright (C) 2012 Opensim Ltd.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//

package inet.applications.voip;

import inet.applications.IUDPApp;


//
// Receives a VoIP stream generated by a SimpleVoIPSender, and records statistics.
// The most important statistic is MOS (Mean Opinion Score, a value between 1 
// and 5, representing a human user's view of the voice quality), computed using 
// the E Model defined in the ITU-T G.107 standard. The parameters starting with
// "emodel_" correspond to the parameters of the E model.
// 
// The E Model was originally developed within ETSI as a transmission planning tool,
// described in ETSI technical report ETR 250, and then standardized by the ITU as G.107.
// The objective of the model was to determine a quality rating that incorporated the
// "mouth to ear" characteristics of a speech path.
//
// The playout delay, buffer space, the UDP port to listen on, and other input 
// can be specified in module parameters.
//
simple SimpleVoIPReceiver like IUDPApp
{
    parameters:
        int localPort;
        int emodel_Ie = default(5);        // Equipment impairment factor
        int emodel_Bpl = default(10);      // Packet-loss robustness factor
        int emodel_A = default(5);         // Advantage factor
        double emodel_Ro = default(93.2);  // Basic signal-to-noise ratio

        double playoutDelay @unit(s) = default(0);      // initial delay for beginning playout after receiving the first packet
        bool adaptivePlayoutDelay = default(false);      // if true, adjust playoutDelay after each talkspurt
        int bufferSpace = default(20);      // buffer size in packets
        double mosSpareTime @unit(s) = default(1s); // spare time before calculating MOS (after calculated playout time of last packet)

        @signal[VoIPPacketDelay](type="simtime_t");      // when receive a frame
        @signal[VoIPPacketLossRate](type="double");      // at end of talkspurt
        @signal[VoIPPlayoutDelay](type="simtime_t");    // at end of talkspurt
        @signal[VoIPPlayoutLossRate](type="double");    // at end of talkspurt
        @signal[VoIPMosSignal](type="double");          // at end of talkspurt
        @signal[VoIPTaildropLossRate](type="double");   // at end of talkspurt
        @statistic[endToEndDelay](title="VoIP Packet End-to-End Delay"; unit="s"; source="VoIPPacketDelay"; record=stats,vector); 
        @statistic[packetLossRate](title="VoIP Packet Loss"; unit="ratio"; source="VoIPPacketLossRate"; record=stats,vector);
        @statistic[playoutDelay](title="VoIP Playout Delay"; unit="s"; source="VoIPPlayoutDelay"; record=stats,vector);
        @statistic[playoutLossRate](title="VoIP Playout Loss Rate"; unit="ratio"; source="VoIPPlayoutLossRate"; record=stats,vector);
        @statistic[MOS](title="VoIP MOS"; unit="MOS"; source="VoIPMosSignal"; record=stats,vector);
        @statistic[taildropLossRate](title="VoIP Tail Drop Loss Rate"; unit="ratio"; source="VoIPTaildropLossRate"; record=stats,vector);

        @display("i=block/source");
    gates:
        output udpOut;
        input udpIn;
}

